package io.adrainty.bolee.file.repository.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.adrainty.bolee.file.mapper.FileMapper;
import io.adrainty.bolee.file.mapper.FilePartMapper;
import io.adrainty.bolee.file.models.bo.FileBO;
import io.adrainty.bolee.file.models.bo.FilePartBO;
import io.adrainty.bolee.file.models.constants.FileConstants;
import io.adrainty.bolee.file.models.entity.FileEntity;
import io.adrainty.bolee.file.models.entity.FilePartEntity;
import io.adrainty.bolee.file.repository.IFileRepository;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;

/**
 * @author AdRainty
 * @version V1.0.0
 * @since 2025/8/17 下午11:48
 */

@Repository
public class FileRepositoryImpl implements IFileRepository {

    @Resource
    private FileMapper fileMapper;

    @Resource
    private FilePartMapper filePartMapper;

    @Override
    public IPage<FileEntity> pageFile(Integer pageNum, Integer pageSize, FileEntity param) {
        Wrapper<FileBO> wrapper = getWrapper(param);
        Page<FileBO> page = new Page<>(pageNum, pageSize);
        return fileMapper.selectPage(page, wrapper).convert(item -> BeanUtil.toBean(item, FileEntity.class));
    }

    @Override
    public FileEntity saveFileBO(FileEntity param) {
        FileBO fileBO = BeanUtil.copyProperties(param, FileBO.class);
        int result = fileMapper.insert(fileBO);
        if (result <= 0) return null;
        return BeanUtil.copyProperties(fileBO, FileEntity.class);
    }

    @Override
    public void saveFilePart(FilePartEntity filePartVO) {
        FilePartBO filePartBO = BeanUtil.copyProperties(filePartVO, FilePartBO.class);
        filePartMapper.insert(filePartBO);
        filePartVO.setCompanyNo(filePartBO.getCompanyNo());
        filePartVO.setId(filePartBO.getId());
    }

    @Override
    public void deleteFilePartByUpLoadId(String uploadId) {
        Wrapper<FilePartBO> wrapper = Wrappers.lambdaQuery(FilePartBO.class)
                .eq(FilePartBO::getUploadId, uploadId);
        filePartMapper.delete(wrapper);
    }

    @Override
    public void updateUpdateStatus(FileEntity fileVO) {
        Wrapper<FileBO> wrapper = Wrappers.lambdaUpdate(FileBO.class)
                .eq(FileBO::getId, fileVO.getId())
                .set(FileBO::getStatus, fileVO.getStatus());
        fileMapper.update(wrapper);
    }

    @Override
    public List<FileEntity> getNeedClearFileList() {
        LocalDateTime localDateTime = LocalDateTime.now().minusSeconds(FileConstants.FILE_DELAY_TIME / 1000);
        Wrapper<FileBO> wrapper = Wrappers.lambdaQuery(FileBO.class)
                .isNull(FileBO::getBusinessId)
                .lt(FileBO::getCreatedTime, localDateTime);
        List<FileBO> fileBOList = fileMapper.selectList(wrapper);
        return BeanUtil.copyToList(fileBOList, FileEntity.class);
    }

    @Override
    public void deleteBatchFile(List<Long> fileListIds) {
        fileMapper.deleteByIds(fileListIds);
    }

    @Override
    public FileEntity getFile(Long fileId) {
        FileBO fileBO = fileMapper.selectById(fileId);
        return BeanUtil.copyProperties(fileBO, FileEntity.class);
    }

    @Override
    public List<FileEntity> getFileListByBusinessId(Long businessId) {
        Wrapper<FileBO> wrapper = Wrappers.lambdaQuery(FileBO.class)
                .eq(FileBO::getBusinessId, businessId);
        List<FileBO> fileBOList = fileMapper.selectList(wrapper);
        return BeanUtil.copyToList(fileBOList, FileEntity.class);
    }

    @Override
    public List<FileEntity> getFileListByBusinessIds(List<Long> businessIds) {
        Wrapper<FileBO> wrapper = Wrappers.lambdaQuery(FileBO.class)
                .in(FileBO::getBusinessId, businessIds);
        List<FileBO> fileBOList = fileMapper.selectList(wrapper);
        return BeanUtil.copyToList(fileBOList, FileEntity.class);
    }

    @Override
    public List<FileEntity> getFileListById(Collection<Long> delIdList) {
        Wrapper<FileBO> wrapper = Wrappers.lambdaQuery(FileBO.class)
                .in(FileBO::getId, delIdList);
        List<FileBO> fileBOList = fileMapper.selectList(wrapper);
        return BeanUtil.copyToList(fileBOList, FileEntity.class);
    }

    @Override
    public void updateBindFile(List<FileEntity> bindFileList) {
        List<FileBO> fileBOList = bindFileList.stream().map(fileVO -> {
            FileBO fileBO = new FileBO();
            fileBO.setId(fileVO.getId());
            fileBO.setBusinessId(fileVO.getBusinessId());
            fileBO.setBusinessType(fileVO.getBusinessType());
            return fileBO;
        }).toList();
        fileMapper.updateById(fileBOList);
    }

    private Wrapper<FileBO> getWrapper(FileEntity param) {
        return Wrappers.lambdaQuery(FileBO.class)
                .eq(StringUtils.isNotBlank(param.getBusinessType()), FileBO::getBusinessType, param.getBusinessType())
                .eq(param.getBusinessId() != null, FileBO::getBusinessId, param.getBusinessId())
                .eq(param.getStatus() != null, FileBO::getStatus, param.getStatus())
                .likeRight(StringUtils.isNotBlank(param.getFileName()), FileBO::getFileName, param.getFileName())
                .likeRight(StringUtils.isNotBlank(param.getPathUrl()), FileBO::getPathUrl, param.getPathUrl())
                .orderByDesc(FileBO::getCreatedTime);
    }

}
